// Copyright  2012 Petr TALLA. [petr.talla@gmail.com]
// This file is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY;  without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
// [http://www.gnu.org/copyleft/lesser.html]
//=============================================================================

package tc.crase.view;

import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Point2D;
import java.util.Iterator;

import tc.common.registry.Ref;
import tc.common.registry.RegistrySys;
import tc.common.registry.Rview;
import tc.common.utility.GrObject;
import tc.common.utility.GrView;
import tc.common.utility.TcCmd;
import tc.common.utility.TcDisplayXY;
import tc.common.utility.Vector2D;

import tc.crase.db.Xattr;
import tc.crase.db.XattrGIT;
import tc.crase.db.XattrGRP;
import tc.crase.db.XattrGXY;
import tc.crase.sys.XobjectEx;
import tc.crase.cmds.CmdEx;

public class ViewGraph extends GrView implements Rview, MouseListener {
	
	public boolean dirty = false;
	
	Refs refs;
	public XattrGRP attrGraph;
	
	@Override
	public boolean getDirty() { return dirty; };
	
	@Override
	public void setDirty(boolean value) { dirty = value; };
	
	@Override
	public void checkPresence() {
		refs.checkPresence();
	}
	
	@Override
	public void onRefChanged(Ref ref) {
		refs.onRefChanged(ref);
	};
	
	@Override
	public void updateRview() { 
		repaint();
	};
	
	public ViewGraph(XattrGRP attrGraph) {
		for (XattrGIT git : attrGraph) { //Loads all databases before references creation
			;
		}
		
		refs = new Refs(this, new FilterGraph(attrGraph));
		this.attrGraph = attrGraph;
		
		RegistrySys.registry.views.add(this);
		objects.add(new GrDocGraph((XobjectEx)attrGraph.parent, this));
		addMouseListener(this);
	}
	
	@Override
	public void paint(Graphics g)
	{	super.paint(g);
	
		/*for (Ref ref : refs.refs) {
			if (ref.original instanceof XobjectEx.ObjEx == false) continue;
			XobjectEx.ObjEx refEx = (XobjectEx.ObjEx)ref.original;
			
			for (Xattr attr : refEx.getObject()) {
				XattrGXY attrGxy = attr.getAsGXY();
				
				if (attrGxy == null) continue;
				
				if (attrGxy.getGroup() != attrGraph) continue;
				
				TcDisplayXY XY = new TcDisplayXY(attrGxy.xy, transf,
						TcDisplayXY.CoordSys.WORLD);
				XY.transform(TcDisplayXY.CoordSys.DEVICE);		
				
				g.fillOval((int)XY.xy.x, (int)XY.xy.y, 10, 10);
				
				break;
			}
		}*/
	}
	
	static public XobjectEx findNearest(GrView view, Point2D.Double pt) {
		XattrGXY result = findNearestGi(view, pt);
		if (result == null) return null;
		return (XobjectEx)result.getParent();
	}
	
	static public XattrGXY findNearestGi(GrView view, Point2D.Double pt) {
		GrDocGraph docGraphGr = null;
				
		Iterator<GrObject> ito = view.objects.iterator();		
		while ( ito.hasNext() ) {
			GrObject obj = ito.next();
			if (obj instanceof GrDocGraph == false) continue;
			docGraphGr = (GrDocGraph)obj;
		}
		
		if (docGraphGr == null) return null;
		
		//DocGraph docGraph = docGraphGr.getDocGraph();
		XattrGRP attrGraph = docGraphGr.getDocGraph();
		double dx0 = 10e10;
		
		XattrGXY itemResult = null;
		
		for (XattrGIT item : attrGraph) {
			//if (xoOnly) {
			if (item instanceof XattrGXY == false) continue;
			//}
			
			XattrGXY itemXY = (XattrGXY)item;
			
			Vector2D dv1 = new Vector2D(pt, itemXY.xy);
			double dx1 = dv1.size();
		    if (itemResult != null) {
		    	if (dx1 > dx0) continue;
		    }
		    
		    itemResult = itemXY;
	    	dx0 = dx1;
		}
		
		return itemResult;
	}
	
	public GrDocGraph getGrDocGraph() {
		for (int i = 0; i < objects.size(); i++) {
			GrObject object = objects.get(i);
			if (object instanceof GrDocGraph == false) continue;
			return (GrDocGraph)object;
		}
		
		return null;
	}
	
	public void mousePressed(MouseEvent e) {
		if (TcCmd.activeCommand instanceof CmdEx == false) return;
		CmdEx cmdex = (CmdEx)TcCmd.activeCommand;
		
		if (e.getButton() == MouseEvent.BUTTON1) {
			TcDisplayXY PT = new TcDisplayXY(new Point2D.Double(e.getPoint().x, e.getPoint().y),
					              transf, TcDisplayXY.CoordSys.DEVICE);
			PT.transform(TcDisplayXY.CoordSys.WORLD);
			
			XobjectEx xo = findNearest(this, PT.xy);
			cmdex.enterSelected(e.getPoint(), this, xo);
		}
		else if (e.getButton() == MouseEvent.BUTTON3) {
			cmdex.enterReset(e.getPoint(), this);
		}
	} 
	public void mouseReleased(MouseEvent e) {}    
	public void mouseDragged(MouseEvent e) {}
	public void mouseClicked(MouseEvent e) {}
	public void mouseEntered(MouseEvent e) {}  
	public void mouseExited(MouseEvent e) {}
	public void mouseMoved(MouseEvent e) {}
	


}
